{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> 原文地址 [www.cnblogs.com](https://www.cnblogs.com/fiona-zhong/p/10249840.html)\n",
    "\n",
    "常量是任何一门语言中都会使用的一种变量类型\n",
    "\n",
    "如 要表示星期常量，我们可能会直接定义一组变量\n",
    "\n",
    "JAN = 1\n",
    "\n",
    "TWO = 2\n",
    "\n",
    "...\n",
    "\n",
    "然后在返回给前端的时候，我们返回的就会是 1,2，... 这种魔法数字，导致后来的人阅读起来很麻烦。\n",
    "\n",
    "在 python 中，为了代码的可读性和简洁性，更建议使用枚举类型\n",
    "\n",
    "1、枚举类型的定义：\n",
    "\n",
    "　　from enum import Enum\n",
    "\n",
    "　　1）可以通过传入 cls_name 和一个可迭代对象来定义\n",
    "\n",
    "　　　传入 **list 列表**\n",
    "\n",
    "　　　week= Enum(\"Week\", ([\"JAN\", \"TUE\",...]))\n",
    "\n",
    "　　　　![](https://img2018.cnblogs.com/blog/1445455/201901/1445455-20190110113705600-1720523774.png)\n",
    "\n",
    "　　　传入 **tuple 元组**\n",
    "\n",
    "　　　week = Enum(\"Week\", (\"JAN\", \"TUE\"))\n",
    "\n",
    "　　　　![](https://img2018.cnblogs.com/blog/1445455/201901/1445455-20190110113716595-206369005.png)\n",
    "\n",
    "　　　传入**字典**\n",
    "\n",
    "　　　week= Enum(\"Week\", ({\"JAN\":\"1\", \"TUE\":\"2\"}))\n",
    "\n",
    "　　　　![](https://img2018.cnblogs.com/blog/1445455/201901/1445455-20190110113731986-252834157.png)\n",
    "\n",
    "　　　传入 **string 字符串**\n",
    "\n",
    " week= Enum(\"Week\", \"JAN TUE\")\n",
    "\n",
    "　　　　![](https://img2018.cnblogs.com/blog/1445455/201901/1445455-20190110113743544-104207916.png)\n",
    "\n",
    "　　2）定义一个类，继承 Enum\n",
    "\n",
    "　　　　class Week(Enum):\n",
    "\n",
    "　　　　　　JAN = 1\n",
    "\n",
    "　　　　　　TUE = 2\n",
    "\n",
    "　　　　![](https://img2018.cnblogs.com/blog/1445455/201901/1445455-20190110113347928-726268842.png)\n",
    "\n",
    "2、枚举类型定义注意事项：\n",
    "\n",
    "　　1）成员名称不能重复, 如果使用相同的 key，会报错 Attempted to reuse key\n",
    "\n",
    "　　　　![](https://img2018.cnblogs.com/blog/1445455/201901/1445455-20190110113837430-2009029719.png)\n",
    "\n",
    "　　2）不同成员的值允许相同，但是对于相同的值的成员，第二个成员名被看做第一个成员名的别名，在遍历的时候，只会遍历出其中一个成员\n",
    "\n",
    "　　　　![](https://img2018.cnblogs.com/blog/1445455/201901/1445455-20190110114447418-285128351.png)\n",
    "\n",
    "　　　　通过值回去枚举成员时，也只能获取一个\n",
    "\n",
    "　　　　![](https://img2018.cnblogs.com/blog/1445455/201901/1445455-20190110114555054-322194289.png)\n",
    "\n",
    "　　3）如果要限制枚举的值不能重复，可以使用装饰器 @unique\n",
    "\n",
    "　　　　使用了 @unique 装饰器，如果值出现重复，会报错：duplicate values\n",
    "\n",
    " 　　　　![](https://img2018.cnblogs.com/blog/1445455/201901/1445455-20190110133401521-1843726049.png)\n",
    "\n",
    "3、枚举取值\n",
    "\n",
    "　　1）通过成员名称来取成员\n",
    "\n",
    " 　　　week.TUE/ week[\"TUE\"]　　--->![](https://img2018.cnblogs.com/blog/1445455/201901/1445455-20190110133724510-1659666419.png)\n",
    "\n",
    "　　　week.TUE.name---->TUE\n",
    "\n",
    "　　　week.TUE.value---->2\n",
    "\n",
    "　　2）通过值来获取成员\n",
    "\n",
    "　　　Week(2)　　------>![](https://img2018.cnblogs.com/blog/1445455/201901/1445455-20190110133912942-806539187.png)\n",
    "\n",
    "　　　Week(2).name---->Tue\n",
    "\n",
    "　　　Week(2).value---->2\n",
    "\n",
    "　　3）遍历取值\n",
    "\n",
    "　　　　for week in Week:\n",
    "\n",
    "　　　　　　print(week)\n",
    "\n",
    "　　　　![](https://img2018.cnblogs.com/blog/1445455/201901/1445455-20190110134141285-1454326463.png)\n",
    "\n",
    "　　　前面说了，如果 Week 中有值重复的成员，那么遍历的时候，只会遍历出一个成员，但是如果想要把所有的成员都遍历出来呢？需要用到__members__属性\n",
    "\n",
    "　　　　for week in Week.__members__.items():\n",
    "\n",
    "　　　　　　print(week)\n",
    "\n",
    "　　　　![](https://img2018.cnblogs.com/blog/1445455/201901/1445455-20190110134722960-42141035.png)\n",
    "\n",
    "4）enum 枚举类型比较\n",
    "\n",
    "　　枚举成员可进行同一性比较\n",
    "\n",
    "　　　　week.JAN is week.TUE---->False\n",
    "\n",
    "　　　　week.JAN is not week.JAN---->False\n",
    "\n",
    "　　枚举成员可进行等值比较\n",
    "\n",
    "　　　　week.JAN.value == \"1\"--->True\n",
    "\n",
    "　　　　week.JAN==week.JAN\n",
    "\n",
    "5）枚举类型的应用：\n",
    "\n",
    "　　【需求】现在做一个注册需求，1）可以通过邮箱密码注册 ；2）可以通过手机号验证码注册；\n",
    "\n",
    "　　针对这个写一个登录 API\n",
    "\n",
    "　　【解析】针对不同的登录类型，传递给后端的字段是不一样的，如邮箱密码登录，需要传递邮箱和密码，手机号验证码登录，需要传递给后台手机号和验证码，所以需要针对不同的登录方式做不同的登录验证。\n",
    "\n",
    "　　这个时候，我们可以使用枚举类型来完成这个需求。\n",
    "\n",
    "　　　　1）定义一个枚举类\n",
    "\n",
    "　　　　　　![](https://img2018.cnblogs.com/blog/1445455/201901/1445455-20190110141343773-576619804.png)\n",
    "\n",
    "　　　　2）定义 register 方法\n",
    "\n",
    "　　　　　　![](https://img2018.cnblogs.com/blog/1445455/201901/1445455-20190110142036036-1407574764.png)\n",
    "\n",
    "　　　　　上面截图中，定义了一个 promise 字典，里面定义了针对不同注册类型的注册方法\n",
    "\n",
    "　　　　　然后根据前端传递过来的 type 值，对应的调用 promise 中的函数\n",
    "\n",
    "　　　　　这里的 form.type.data 是枚举类型，并不是枚举值，在定义 form 验证的时候，将枚举类型赋值给了 type.data, 所以可以直接使用 promise[form.type.data] 调用\n",
    "\n",
    "　　　　　　![](https://img2018.cnblogs.com/blog/1445455/201901/1445455-20190110143409469-1372795311.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
